/**
 * @file wa_win.c
 *
 */

 /*********************
  *      INCLUDES
  *********************/
#include "wa_conf.h"
#if USE_WA_WIN != 0
#include "wa_win.h"

/*********************
*      DEFINES
*********************/

/**********************
*      TYPEDEFS
**********************/

/**********************
*  STATIC PROTOTYPES
**********************/

static wa_obj_callback ancestor_callback;
static void wa_win_callback(wa_sign* sign);

/**********************
 *  STATIC VARIABLES
 **********************/


/**********************
 *      MACROS
 **********************/

 /**********************
  *   GLOBAL FUNCTIONS
  **********************/

/**
* win module init
*/
void wa_win_module_init(void)
{
}

/**
* create a win
* @param par
* @return win obj
*/
wa_obj* wa_win_create(wa_obj* par)
{
	wa_obj* new_win;
	wa_win_ext* win_ext;

	new_win = wa_obj_create(par, NULL);
	if (new_win == NULL)
	{
		return new_win;
	}
	if (ancestor_callback == NULL)
	{
		ancestor_callback = wa_obj_get_callback(new_win);
	}

	win_ext = wa_obj_malloc_ext_attr(new_win, sizeof(wa_win_ext));
	if (win_ext == NULL)
	{
		return NULL;
	}
	win_ext->center = wa_obj_create(new_win, NULL);
	if (win_ext->center == NULL)
	{
		return NULL;
	}
	win_ext->panel = wa_panel_create(win_ext->center);
	if (win_ext->panel == NULL)
	{
		return NULL;
	}

	win_ext->edge_show = wa_nok;
	win_ext->edge_size = 1;
	win_ext->edge_color = WA_COLOR_FOREGROUND;

	wa_obj_set_callback(new_win, wa_win_callback);

	return new_win;
}

/**
* win set pos
* @param win
* @param x
* @param y
*/
void wa_win_set_pos(wa_obj* win, int x, int y)
{
	wa_win_ext* ext;
	ext = wa_obj_get_ext_attr(win);
	wa_obj_set_pos(win, x, y);
	if (ext->edge_show == wa_ok)
	{
		wa_obj_set_pos(ext->center, ext->edge_size, ext->edge_size);
		wa_obj_set_pos(ext->panel, 0, 0);
	}
	else
	{
		wa_obj_set_pos(ext->center, 0, 0);
		wa_obj_set_pos(ext->panel, 0, 0);
	}
}

/**
* win set size
* @param win
* @param width
* @param height
*/
void wa_win_set_size(wa_obj* win, int width, int height)
{
	wa_win_ext* ext;
	ext = wa_obj_get_ext_attr(win);
	wa_obj_set_size(win, width, height);
	if (ext->edge_show == wa_ok)
	{
		wa_obj_set_size(ext->center, width - 2 * ext->edge_size, height - 2 * ext->edge_size);
		wa_obj_set_size(ext->panel, width - 2 * ext->edge_size, height - 2 * ext->edge_size);
	}
	else
	{
		wa_obj_set_size(ext->center, width, height);
		wa_obj_set_size(ext->panel, width, height);
	}
}

/**
* win set edge size
* @param win
* @param edge size
*/
void wa_win_set_edge_size(wa_obj* win, int edge_size)
{
	wa_win_ext* ext;
	ext = wa_obj_get_ext_attr(win);
	ext->edge_size = edge_size;
	if (ext->edge_show == wa_ok)
	{
		int width, height;
		width = wa_obj_get_width(win);
		height = wa_obj_get_height(win);
		wa_obj_set_pos(ext->center, ext->edge_size, ext->edge_size);
		wa_obj_set_pos(ext->panel, 0, 0);
		wa_obj_set_size(ext->center, width - 2 * ext->edge_size, height - 2 * ext->edge_size);
		wa_obj_set_size(ext->panel, width - 2 * ext->edge_size, height - 2 * ext->edge_size);
		wa_obj_invalidate(win);
	}
}

/**
* win set edge or not
* @param win
* @param show
*/
void wa_win_set_edge_show(wa_obj* win, wa_result show)
{
	wa_win_ext* ext;
	ext = wa_obj_get_ext_attr(win);
	ext->edge_show = show;
	if (ext->edge_show == wa_ok)
	{
		int width, height;
		width = wa_obj_get_width(win);
		height = wa_obj_get_height(win);
		wa_obj_set_pos(ext->center, ext->edge_size, ext->edge_size);
		wa_obj_set_pos(ext->panel, 0, 0);
		wa_obj_set_size(ext->center, width - 2 * ext->edge_size, height - 2 * ext->edge_size);
		wa_obj_set_size(ext->panel, width - 2 * ext->edge_size, height - 2 * ext->edge_size);
	}
	else
	{
		int width, height;
		width = wa_obj_get_width(win);
		height = wa_obj_get_height(win);
		wa_obj_set_pos(ext->center, 0, 0);
		wa_obj_set_pos(ext->panel, 0, 0);
		wa_obj_set_size(ext->center, width, height);
		wa_obj_set_size(ext->panel, width, height);
	}
	wa_obj_invalidate(win);
}

/**
* win set edge color
* @param win
* @param show
*/
void wa_win_set_edge_color(wa_obj* win, wa_gui_color edge_color)
{
	wa_win_ext* ext;
	ext = wa_obj_get_ext_attr(win);
	ext->edge_color = edge_color;
	if (ext->edge_show == wa_ok)
	{
		wa_obj_invalidate(win);
	}
}

/**
* win set callback
* @param win
* @param cb
*/
void wa_win_set_callback(wa_obj* win, wa_obj_callback cb)
{
	wa_win_ext* ext;
	ext = wa_obj_get_ext_attr(win);
	wa_panel_set_callback(ext->panel, cb);
}

/**
* add a obj to win
* @param win
* @param obj
*/
void wa_win_add_obj(wa_obj* win, wa_obj* obj)
{
	wa_win_ext* ext;
	ext = wa_obj_get_ext_attr(win);
	wa_obj_set_parent(obj, ext->panel);
}

/**
* get this win obj in it's callback
* @param the dst obj in callback 
*/
wa_obj* wa_win_get_obj_in_cb(wa_obj* obj)
{
	return obj->par->par;
}

/**
* set panel pos rel center
* @param win
* @param rel_x
* @param rel_y
*/
void wa_win_set_panel_rel_pos(wa_obj* win, int rel_x, int rel_y)
{
	wa_win_ext* ext;
	ext = wa_obj_get_ext_attr(win);
	wa_obj_set_pos(ext->panel, rel_x, rel_y);
}

/**
* set panel pos rel size
* @param win
* @param rel_w
* @param rel_h
*/
void wa_win_set_panel_rel_size(wa_obj* win, int rel_w, int rel_h)
{
	int width, height;
	wa_win_ext* ext;
	ext = wa_obj_get_ext_attr(win);
	width = wa_obj_get_width(ext->center);
	height = wa_obj_get_height(ext->center);
	wa_obj_set_size(ext->panel, width + rel_w, height + rel_h);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

 /**
 * win obj redraw function
 * @param obj
 */
static void _Paint(wa_obj* obj)
{
	wa_win_ext* ext;
	ext = wa_obj_get_ext_attr(obj);

	if (ext->edge_show == wa_ok)
	{
		int i;
		for (i = 0; i < ext->edge_size; i++)
		{
			wa_mask_drawrect(obj->rect.x1 + i, obj->rect.y1 + i,
				wa_obj_get_width(obj)- 2 * i,
				wa_obj_get_height(obj)- 2 * i,
				&(obj->redraw_rect),
				ext->edge_color);
		}
	}
}

/**
 * win obj delete function
 * @param obj
 */
static void _Delete(wa_obj* obj)
{
	
}

/**
 * win obj callback function
 * @param sign
 */
static void wa_win_callback(wa_sign* sign)
{
	int sign_id;
	wa_obj* obj;

	ancestor_callback(sign);
	sign_id = sign->sign_id;
	obj = sign->obj_dst;

	switch (sign_id)
	{
		case WA_SIGNAL_PAINT:
		{
			_Paint(obj);
			break;
		}
		case WA_SIGNAL_DELETE:
		{
			_Delete(obj);
			break;
		}
		default:
		{
			break;
		}
	}
}

#endif
